package wxcloud

import (
	"fmt"
	"net/http"
	"sync"

	"github.com/mars/internal/admin/core/domain"
	genericOpts "github.com/mars/internal/pkg/options"
	"github.com/mars/internal/pkg/wxcloud"
)

type WxCloudFactory struct {
	wxcloud *wxcloud.WxCloudClient
}

var _ domain.Factory = (*WxCloudFactory)(nil)

var (
	wxCloudFactory domain.Factory
	once           sync.Once
)

func GetWxCloudFactory(wxcloudOpts *genericOpts.WxCloudOptions, httpClient *http.Client) (domain.Factory, error) {
	if wxCloudFactory != nil {
		return wxCloudFactory, nil
	}

	if wxcloudOpts == nil && wxCloudFactory == nil {
		return nil, fmt.Errorf("failed to get wxcloud store fatory")
	}
	once.Do(func() {
		wxcloudClient := wxcloud.NewWxCloudClient(wxcloudOpts, httpClient)
		wxCloudFactory = &WxCloudFactory{wxcloud: wxcloudClient}
	})

	return wxCloudFactory, nil
}

// Close implements domain.Factory.
func (w *WxCloudFactory) Close() error {
	panic("unimplemented")
}

// Init implements domain.Factory.
func (w *WxCloudFactory) Init() error {
	panic("unimplemented")
}

// UserDomain implements domain.Factory.
func (w *WxCloudFactory) UserDomain() domain.UserGateway {
	return newUserGatewayImpl(w.wxcloud)
}

// BookingGateway implements domain.Factory.
func (w *WxCloudFactory) BookingGateway() domain.BookingGateway {
	return newBookingGatewayImpl(w.wxcloud)
}

// OrderGateway implements domain.Factory.
func (w *WxCloudFactory) OrderGateway() domain.OrderGateway {
	return newOrderGatewayImpl(w.wxcloud)
}

// ProductGateway implements domain.Factory.
func (w *WxCloudFactory) ProductGateway() domain.ProductGateway {
	return newProductGatewayImpl(w.wxcloud)
}

// CartDomain implements domain.Factory.
func (w *WxCloudFactory) CartDomain() domain.CartGateway {
	return NewCartGateway(w.wxcloud, w.ProductGateway())
}

// GetWxCloudClient 返回内部的 WxCloudClient 实例
func (w *WxCloudFactory) GetWxCloudClient() *wxcloud.WxCloudClient {
	return w.wxcloud
}
